package com.edgar.common.simple.animation;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Rect;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.ViewAnimator;

import com.edgar.common.simple.R;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by edgar on 2016/6/10.
 */
public class ExpandOpenListAdapter extends BaseAdapter{

    private Context mContext;
    private final int mHeight;
    private ListView mListView;
    private int mExpandId = -1;
    private ViewHolder mExpandHolder;
    private final List<TestModer> mDataList = new ArrayList<>();

    private final Runnable mScrollRunnable = new Runnable() {
        @Override
        public void run() {
            if (mExpandHolder != null){
                ViewGroup itemView = (ViewGroup) mExpandHolder.itemMenuView.getParent();
                Rect rect = new Rect(itemView.getLeft(),itemView.getTop(),itemView.getRight(),itemView.getBottom());
                mListView.requestChildRectangleOnScreen(itemView,rect,false);
            }
        }
    };

    public ExpandOpenListAdapter(Context context, ListView listView){
        mContext = context;
        mHeight = mContext.getResources().getDimensionPixelSize(R.dimen.item_menu_height);
        mListView = listView;
        for (int i = 0; i < 20; i++) {
            TestModer testModer = new TestModer();
            testModer.id = i+10;
            testModer.name = "Test Moder:"+i;
            mDataList.add(testModer);
        }
    }

    @Override
    public int getCount() {
        return mDataList.size();
    }

    @Override
    public Object getItem(int position) {
        return mDataList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null){
            convertView = LayoutInflater.from(mContext).inflate(R.layout.expand_open_list_item,null);
            holder = new ViewHolder();
            holder.itemTitleView = (TextView) convertView.findViewById(R.id.item_title);
            holder.itemMenuView = convertView.findViewById(R.id.item_menu);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        final TestModer testModer = (TestModer) getItem(position);
        holder.itemTitleView.setText(testModer.name);
        holder.itemMenuView.setVisibility(View.GONE);
        holder.isExpand = false;
        holder.position = position;
        if (testModer.id == mExpandId){
            mExpandHolder = holder;
            mExpandHolder.isExpand = true;
            holder.itemMenuView.setVisibility(View.VISIBLE);
        }
        holder.itemModer = testModer;
        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View v) {
                final ViewHolder viewHolder = (ViewHolder) v.getTag();
                if (mExpandId == viewHolder.itemModer.id){
                    closeMenu(viewHolder,true);
                } else {
                    expandMenu(viewHolder,true);
                }
            }
        });
        return convertView;
    }

    private void expandMenu(final ViewHolder holder,boolean animation){
        if (mExpandHolder != null && mExpandHolder != holder && mExpandHolder.isExpand){
            closeMenu(mExpandHolder,animation);
        }
        mExpandId = holder.itemModer.id;
        mExpandHolder = holder;
        final int startHeight = holder.itemMenuView.getHeight();
        holder.itemMenuView.setVisibility(View.VISIBLE);
        if (animation){
            final ViewTreeObserver viewTreeObserver = mListView.getViewTreeObserver();
            viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    if (viewTreeObserver.isAlive()){
                        viewTreeObserver.removeOnPreDrawListener(this);
                    }
                    int endHeight = holder.itemMenuView.getHeight();
                    final int distance = endHeight - startHeight;
                    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) holder.itemMenuView.getLayoutParams();
                    params.bottomMargin = -mHeight;
                    params.height = mHeight;
                    holder.itemMenuView.requestLayout();
                    AnimatorSet animatorSet = new AnimatorSet();
                    ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f,1f);
                    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                        @Override
                        public void onAnimationUpdate(ValueAnimator animation) {
                            float value = (float) animation.getAnimatedValue();
                            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) holder.itemMenuView.getLayoutParams();
                            params.bottomMargin = -(int)((1-value)*mHeight);
                            holder.itemMenuView.requestLayout();
                        }
                    });
                    valueAnimator.addListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            super.onAnimationEnd(animation);
                            if (holder.position == mListView.getLastVisiblePosition()){
                                mListView.smoothScrollToPositionFromTop(holder.position,0);
                            }
                        }
                    });
                    valueAnimator.setDuration(300);
                    valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
                    valueAnimator.start();
                    return false;
                }
            });
        }
    }

    private void closeMenu(final ViewHolder holder,boolean animation){
        holder.itemMenuView.setVisibility(View.GONE);
        mExpandId = -1;
        mExpandHolder = null;
        if (animation){
            final ViewTreeObserver viewTreeObserver = mListView.getViewTreeObserver();
            viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    if (viewTreeObserver.isAlive()){
                        viewTreeObserver.removeOnPreDrawListener(this);
                    }
                    holder.itemMenuView.setVisibility(View.VISIBLE);
                    ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f,1f);
                    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                        @Override
                        public void onAnimationUpdate(ValueAnimator animation) {
                            float value = (float) animation.getAnimatedValue();
                            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) holder.itemMenuView.getLayoutParams();
                            params.bottomMargin = (int) (value*mHeight);
                            holder.itemMenuView.requestLayout();
                        }
                    });
                    valueAnimator.setDuration(300);
                    valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
                    valueAnimator.addListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            super.onAnimationEnd(animation);
                            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) holder.itemMenuView.getLayoutParams();
                            params.height = 0;
                            holder.itemMenuView.setVisibility(View.GONE);
                        }
                    });
                    valueAnimator.start();
                    return false;
                }
            });
        }
    }

    private static class ViewHolder{
        private TextView itemTitleView;
        private View itemMenuView;
        private TestModer itemModer;
        private boolean isExpand;
        private int position;
    }
}